/**
 * 拖动元素
 */
export class DragEl {
  dragging = false
  clientX = 0
  clientY = 0
  translate = [0, 0]
  left = 0
  top = 0
  transform = ''

  /**
   *
   * @param {HTMLElement} triggerEl 触发拖动的元素,比如卡片的header部分
   * @param {HTMLElement} dragEl 拖动的元素。比如一个卡片
   */
  constructor(triggerEl, dragEl) {
    this.triggerEl = triggerEl
    this.dragEl = dragEl
    this.#init()
  }
  #init() {
    this.triggerEl.addEventListener('mousedown', this.#handleMouseDown)
    document.addEventListener('mouseup', this.#handleMouseUp)
    document.addEventListener('mousemove', this.#handleMouseMove)
  }
  #handleMouseDown = (e) => {
    this.dragging = true

    const dom = this.dragEl
    dom.style.cursor = 'move'
    dom.style.userSelect = 'none'

    this.clientX = e.clientX
    this.clientY = e.clientY
    this.translate = [0, 0]
    this.left = dom.offsetLeft
    this.top = dom.offsetTop
    this.transform = window.getComputedStyle(dom).transform
    if (this.transform === 'none') this.transform = ''
  }
  #handleMouseUp = () => {
    this.dragging = false

    const dom = this.dragEl
    dom.style.cursor = 'auto'
    dom.style.userSelect = 'auto'
    dom.style.left = this.left + this.translate[0] + 'px'
    dom.style.top = this.top + this.translate[1] + 'px'
    dom.style.transform = this.transform
  }
  #handleMouseMove = (e) => {
    if (!this.dragging) return

    const dom = this.dragEl
    const dx = e.clientX - this.clientX
    const dy = e.clientY - this.clientY

    let newX = this.left + dx
    let newY = this.top + dy

    const margin = -10
    const maxX = window.innerWidth - dom.offsetWidth - margin
    const maxY = window.innerHeight - dom.offsetHeight - margin

    newX = Math.max(margin, Math.min(newX, maxX))
    newY = Math.max(margin, Math.min(newY, maxY))

    this.translate = [newX - this.left, newY - this.top]
    dom.style.transform = `translate(${this.translate[0]}px, ${this.translate[1]}px) ${this.transform}`
  }
  dispose() {
    this.triggerEl.removeEventListener('mousedown', this.#handleMouseDown)
    document.removeEventListener('mouseup', this.#handleMouseUp)
    document.removeEventListener('mousemove', this.#handleMouseMove)
  }
}
